/**
@description base文件

@copyright    Copyright 2021 高灯科技
@version      1.0.0
@link         https://www.goldentec.com
@author       venki.chen <venki.chen@goldentec.com>
@datetime     2021/11/18 9:29
*/

package base

import (
	"encoding/json"
	"fmt"
	"reflect"
	"time"
)

type person struct {
	Name    string   `info:"name" sub:"作者姓名"`
	Age     int      `info:"age" sub:"作者年龄"`
	Address string   `json:"address"`
	Family  []string `json:"family"`
}

func init() {
	fmt.Println("base模块初始化成功...")
}

func AccessBase() {
	// 结构体标签
	/*var p person.pb
	structLearn(&p)*/
	/*p := person.pb{
		Name:    "陈文小超",
		Age:     29,
		Address: "广东深圳",
		Family:  []string{"北京", "上海", "广州"},
	}
	structJson(p)*/

	// 协程学习
	// goroutineLearn()

	// channel学习
	// channelLearn()

	// 带缓存的channel学习
	// channelCacheLearn()

	// select学习
	selectLearn()
}

// select学习
func selectLearn() {
	chann1 := make(chan int)
	chann2 := make(chan int)

	go func() {
		for i := 0; i < 10; i++ {
			defer fmt.Printf("go协程执行结束%v\n...", i+1)
			fmt.Println(<-chann1)
		}
		chann2 <- 0
	}()
	x, y := 1, 1
	for {
		select {
		case chann1 <- x:
			x = y
			y = x + y
		case <-chann2:
			fmt.Println("go协程结束2...")
			return
		}
	}
}

// 带缓存的channel学习
func channelCacheLearn() {
	chann := make(chan int, 3) // 指定管道容量即意味着携带缓存

	go func() {
		defer fmt.Println("go 协程执行结束...")
		for i := 0; i < 3; i++ {
			chann <- i
			fmt.Println("协程正在执行...", "写入数据是：", i, "此时的管道长度是：", len(chann), "管道容量是：", cap(chann))
		}
	}()
	time.Sleep(2 * time.Second)
	for i := 0; i < 3; i++ {
		num := <-chann
		fmt.Printf("第%d个num是：%v\n", i+1, num)
	}

	fmt.Println("主线程执行结束...")
}

// channel学习
func channelLearn() {
	chann := make(chan int)
	go func() {
		defer fmt.Println("go协程执行结束...")
		fmt.Println("go协程执行中...")
		chann <- 666
	}()
	num := <-chann
	fmt.Println("num=", num)
	fmt.Println("主线程执行结束...")
}

// 协程学习
func goroutineLearn() {
	go func(a int, b int) bool {
		fmt.Println(a + b)
		return true
	}(10, 20)

	for true {
		time.Sleep(time.Second * 1)
	}
}

// json和struct
func structJson(p person) {
	// 结构体转json
	jsonStr, err := json.Marshal(p)
	if err != nil {
		fmt.Println(err)
		return
	}
	fmt.Printf("jsonStr=%v\n", string(jsonStr))

	// json转结构体
	var pp person
	err = json.Unmarshal(jsonStr, &pp)
	if err != nil {
		fmt.Println(err)
		return
	}
	fmt.Printf("pp=%v\n", pp)
}

// 结构体标签学习
func structLearn(s interface{}) {
	t := reflect.TypeOf(s)
	fmt.Println("--1--,t=", t) // --1--,t= *base.person.pb
	e := t.Elem()
	fmt.Println("--2--,e=", e) // --2--,e= base.person.pb

	for i := 0; i < e.NumField(); i++ {
		tagInfo := e.Field(i).Tag.Get("info")
		tagSub := e.Field(i).Tag.Get("sub")
		fmt.Println("--3--,tageInfo=", tagInfo, "--4--,tagSub=", tagSub)
		// --3--,tageInfo= name --4--,tagSub= 作者姓名
		// --3--,tageInfo= age --4--,tagSub= 作者年龄
	}
}
